package ru.urfc.portal.ui.client;

import java.util.HashMap;
import java.util.Map;

import ru.urfc.portal.ui.client.model.catalogs.CatalogItemWithStyle;
import ru.urfc.portal.ui.client.model.catalogs.UnknownCatalogItem;
import ru.urfc.portal.ui.client.model.catalogs.booleans.BooleanCatalogItem;

public class EnumRegistry {
	
	static private Map<Class<?>, Map<String, Enum<?>>> enumClasses =
		new HashMap<Class<?>, Map<String, Enum<?>>>(); 
	static private Map<Class<?>, Map<String, CatalogItemWithStyle>> catalogItemClasses =
		new HashMap<Class<?>, Map<String, CatalogItemWithStyle>>(); 

	@SuppressWarnings("unchecked")
	public static <T> T getEnum(Class<T> klass, String key) {
		Map<String, Enum<?>> values = enumClasses.containsKey(klass)?
				enumClasses.get(klass): registerEnum((Class<Enum<?>>) klass);
		return (T) values.get(key);
	}

	private static Map<String, Enum<?>> registerEnum(Class<Enum<?>> klass) {
		HashMap<String, Enum<?>> result = new HashMap<String, Enum<?>>();
		for (Enum<?> value: klass.getEnumConstants()) {
			result.put(value.name(), value);
		}
		enumClasses.put(klass, result);
		return result;
	}

	public static CatalogItemWithStyle getCatalogItem(Class<? extends CatalogItemWithStyle> klass, String code, String text) {
		Map<String, CatalogItemWithStyle> values = getCatalog(klass);
		return values.get(code) == null? new UnknownCatalogItem(code, text): values.get(code);
	}	
	
	public static BooleanCatalogItem getCatalogItem(Class<? extends BooleanCatalogItem> klass, Boolean code) {
		Map<String, CatalogItemWithStyle> values = getCatalog(klass);
		return (BooleanCatalogItem) values.get(code.toString());
	}

	private static Map<String, CatalogItemWithStyle> getCatalog(Class<? extends CatalogItemWithStyle> klass) {
		Map<String, CatalogItemWithStyle> values = catalogItemClasses.get(klass);
		if (values == null) {
			throw new RuntimeException("Class " + klass.getName() + " is not registered");
		}
		return values;
	}	
	
	public static void register(CatalogItemWithStyle catalogItemWithStyle) {
		Class<?> klass = catalogItemWithStyle.getClass().getSuperclass();
		Map<String, CatalogItemWithStyle> map = catalogItemClasses.get(klass);
		if (map == null) {
			map = new HashMap<String, CatalogItemWithStyle>();
			catalogItemClasses.put(klass, map);
		}
		map.put(catalogItemWithStyle.getCode(), catalogItemWithStyle);
	}
	
	public static void register(CatalogItemWithStyle[] items) {
		for (CatalogItemWithStyle item: items) {
			register(item);
		}
	}

}
